/* Copyright 2007 dnAnalytics Project.
 *
 * Contributors to this file:
 * Patrick van der Velde
 * Marcus Cuda
 *
 * This file is part of dnAnalytics.  dnAnalytics is licensed under the 
 * Microsoft Public License. See License.txt for a complete copy of the
 * license.
 */

using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;
using System.Security.Permissions;

namespace dnAnalytics
{
    /// <summary>
    /// Extends the base dnAnalytics exception to specify which parameter caused the exception.
    /// </summary>
    [SuppressMessage("Microsoft.Naming", "CA1706:ShortAcronymsShouldBeUppercase"), SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly")]
    [Serializable]
    public abstract class dnAnalyticsArgumentException : dnAnalyticsException
    {
        private readonly string _parameter;

        ///<summary>Initializes a new instance of the <strong>dnAnalyticsArgumentException</strong> class.</summary>
        protected dnAnalyticsArgumentException()
        {
        }

        ///<summary>Initializes a new instance of the <strong>dnAnalyticsArgumentException</strong> class with a specified error message.</summary>
        ///<param name="message">The error message that explains the reason for the exception.</param>
        protected dnAnalyticsArgumentException(string message) : base(message)
        {
        }

        ///<summary>Initializes a new instance of the <strong>dnAnalyticsArgumentException</strong> class with a specified error message 
        ///and a reference to the inner exception that is the cause of this exception.</summary>
        ///<param name="message">The error message that explains the reason for the exception.</param>
        ///<param name="inner">The exception that is the cause of the current exception. 
        ///If the innerException parameter is not a null reference, the current exception is raised in a <strong>catch</strong> block 
        ///that handles the inner exception.</param>
        protected dnAnalyticsArgumentException(string message, Exception inner) : base(message, inner)
        {
        }

        ///<summary>Initializes a new instance of the <strong>dnAnalyticsArgumentException</strong> class with serialized data.</summary>
        ///<param name="info">The error message that explains the reason for the exception.</param>
        ///<param name="context">The error message that explains the reason for the exception.</param>
        protected dnAnalyticsArgumentException(SerializationInfo info, StreamingContext context) : base(info, context)
        {
        }

        ///<summary>Initializes a new instance of the <strong>dnAnalyticsArgumentException</strong> class with a specified error message.</summary>
        ///<param name="message">The error message that explains the reason for the exception.</param>
        ///<param name="parameter">The parameter that caused the exception.</param>
        protected dnAnalyticsArgumentException(string message, string parameter)
            : base(message)
        {
            _parameter = parameter;
        }

        ///<summary>Initializes a new instance of the <strong>dnAnalyticsArgumentException</strong> class with a specified error message 
        ///and a reference to the inner exception that is the cause of this exception.</summary>
        ///<param name="message">The error message that explains the reason for the exception.</param>
        ///<param name="parameter">The parameter that caused the exception.</param>
        ///<param name="inner">The exception that is the cause of the current exception. 
        ///If the innerException parameter is not a null reference, the current exception is raised in a <strong>catch</strong> block 
        ///that handles the inner exception.</param>
        protected dnAnalyticsArgumentException(String message, String parameter, Exception inner)
            : base(message, inner)
        {
            _parameter = parameter;
        }

        /// <summary>
        /// A text string describing the details of the exception. If the parameter name is give, it will 
        /// be prefixed to the message.
        /// </summary>
        public override string Message
        {
            get
            {
                if (string.IsNullOrEmpty(_parameter))
                {
                    return base.Message;
                }
                return _parameter + " : " + base.Message;
            }
        }

        /// <summary>
        /// The parameter that caused the exception.
        /// </summary>
        public virtual string Parameter
        {
            get { return _parameter; }
        }


        /// <summary>
        /// Populates a <see cref="SerializationInfo"/> with the data needed to serialize the exception.
        /// </summary>
        /// <param name="info">The <see cref="SerializationInfo"/> to populate with data</param>.
        /// <param name="context">The destination (see <see cref="StreamingContext"/>) for this serialization.</param>
        [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            if (info == null)
            {
                throw new ArgumentNullException("info");
            }
            info.AddValue("parameter", _parameter);
            base.GetObjectData(info, context);
        }
    }
}